﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Us.Mil.Osd.Acq.Damir.Test.Expressions;
using System.Linq.Expressions;

namespace Us.Mil.Osd.Acq.Damir.Test.ExpressionVisitors
{

	internal class SelectExpressionFinder : ExpressionVisitor
	{
		internal SelectExpression found;
		/// <summary>
		/// Finds and returns the first SelectExpression it encounters.
		/// </summary>
		/// <param name="expression"></param>
		/// <returns></returns>
		public static SelectExpression Find(Expression expression) {
			var finder = new SelectExpressionFinder();			
			finder.Visit(expression);
			return finder.found;
		}
		public override Expression Visit(Expression node) {
			switch ((DbExpressionType)node.NodeType) {
				case DbExpressionType.Select:
					this.found = (SelectExpression)node;
					return this.found;
				case DbExpressionType.Where:
				case DbExpressionType.PredicateJoin:
					return this.Visit(((PredicateExpression)node).Expression);
				case DbExpressionType.Join:
					this.found = this.Visit(((JoinExpression)node).First) as SelectExpression;
					if (this.found == null) {
						this.found = this.Visit(((JoinExpression)node).Second) as SelectExpression;
					}
					if (this.found == null) {
						this.found = this.Visit(((JoinExpression)node).Result) as SelectExpression;
					}
					return this.found;
				case DbExpressionType.SelectMany:
					this.found = this.Visit(((SelectManyExpression)node).First) as SelectExpression;
					if (this.found == null) {
						this.found = this.Visit(((SelectManyExpression)node).Second) as SelectExpression;
					}					
					return this.found;
			}
			if (node.CanReduce) {
				return base.Visit(node);
			}
			return node;
		}
	}
}
